package cn.yuyiling.jelly.srai.service.impl;

import cn.yuyiling.jelly.kg.api.KnowledgePointService;
import cn.yuyiling.jelly.kgai.config.LLMConfigManager;
import cn.yuyiling.jelly.qa.api.QuestionService;
import cn.yuyiling.jelly.qa.mongodb.entity.Question;
import cn.yuyiling.jelly.sr.api.KnowledgeProgressService;
import cn.yuyiling.jelly.sr.mongodb.entity.KnowledgePointProgress;
import cn.yuyiling.jelly.srai.api.RecommendQuestionsService;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.model.ChatModel;

import java.util.*;
import java.util.stream.Collectors;

@DubboService
public class RecommendQuestionsServiceImpl implements RecommendQuestionsService {

    private static final Logger logger = LoggerFactory.getLogger(RecommendQuestionsServiceImpl.class);

    private final ChatClient chatClient;

    @DubboReference
    private KnowledgeProgressService knowledgeProgressService;
    @DubboReference
    private QuestionService questionService;
    @DubboReference
    private KnowledgePointService knowledgePointService;

    public RecommendQuestionsServiceImpl(ChatModel chatModel) {
        logger.info("KgAiConfig init");
        LLMConfigManager configManager = new LLMConfigManager();
        String model = configManager.getModel();
        String token = configManager.getToken();
        int timeout = configManager.getTimeout();
        String defaultSystem = configManager.getDefaultSystem();
        logger.info("KgAiConfig init {}", model);
        logger.info("KgAiConfig init {}", token);
        logger.info("KgAiConfig init {}", timeout);
        logger.info("KgAiConfig init {}", defaultSystem);
        this.chatClient = ChatClient.builder(chatModel)
                // 实现 Logger 的 Advisor
                .defaultAdvisors(
                        new SimpleLoggerAdvisor()
                )
                // 设置 ChatClient 中 ChatModel 的 Options 参数
                .defaultOptions(
                        DashScopeChatOptions.builder()
                                .withModel(model)
                                .build()
                )
                .defaultSystem(defaultSystem)
                .build();

    }

    @Override
    public List<Question> recommendQuestionsByWeakness(String userId) {
        // 获取用户所有知识点掌握情况
        List<KnowledgePointProgress> progressList = knowledgeProgressService.findByUserId(userId);

        if (progressList.isEmpty()) {
            logger.info("No knowledge point progress found for user: " + userId);
            return Collections.emptyList(); // 如果没有记录，则无推荐
        }

        // 计算每个知识点的推荐权重
        Map<String, Double> weightMap = new HashMap<>();
        for (KnowledgePointProgress progress : progressList) {
            double accuracy = progress.getCompletionRate() / 100.0; // 将正确率转换为 0~1 的值
            int practiceCount = progress.getPracticeCount();
            double decayFactor = 1.0 / (1 + practiceCount); // 衰减因子

            String prompt = """
            请评估以下知识点的重要性（满分1.0）：
            - 如果是基础核心概念，权重接近1.0；
            - 如果是边缘或进阶内容，权重较低。
            要求：
            - 只需输出一个表示分数的一位小数（例如：0.8）。
            - 不要添加任何解释、文字或格式。
            知识点：%s
            """;

            String knowledgePointId = progress.getKnowledgePointId();
            String knowledgePoint = knowledgePointService.getKnowledgePointById(knowledgePointId).getName();
            String response = chatClient.prompt()
                    .user(String.format(prompt, knowledgePoint))
                    .call()
                    .content();
            Double score = Double.parseDouble(response.trim());
            double weight = (1 - accuracy) * score * decayFactor;
            weightMap.put(progress.getKnowledgePointId(), weight);
        }

        // 获取所有相关问题
        List<String> knowledgePointIds = new ArrayList<>(weightMap.keySet());
        List<String> knowledgePointNames = new ArrayList<>();
        for(String knowledgePointId : knowledgePointIds){
            String knowledgePointName = knowledgePointService.getKnowledgePointById(knowledgePointId).getName();
            knowledgePointNames.add(knowledgePointName);
        }
        List<Question> questions = questionService.findByKnowledgePointsIn(knowledgePointNames);

        // 根据推荐权重排序
        return questions.stream()
                .sorted((q1, q2) -> {
                    double score1 = calculateWeightedScore(q1, weightMap);
                    double score2 = calculateWeightedScore(q2, weightMap);
                    return Double.compare(score2, score1); // 按降序排序
                })
                .limit(3)
                .collect(Collectors.toList());
    }

    private double calculateWeightedScore(Question question, Map<String, Double> weightMap) {
        return question.getKnowledgePoints().stream()
                .mapToDouble(weightMap::get)
                .sum();
    }

}